#pragma once
#include <vector>
#include <iostream>
#include <memory>
#include "umtl/parallel/thread.hpp"

class logger_t
{
public:
	typedef std::wostream stream_t;
	typedef std::tr1::reference_wrapper< stream_t > stream_ref;
	typedef std::vector< stream_ref > log_streams_t;

	logger_t();
	virtual ~logger_t();

	void add_stream( stream_t& stream );
	void erase_stream( stream_t& stream );

	logger_t& operator<<( stream_t& (*pf)(stream_t&) );
	
	template<typename data_type>
	logger_t& operator<<( data_type const& data );

private:
	log_streams_t log_streams;
	umtl::parallel::critical_section ct;

	log_streams_t::iterator logger_t::find( stream_t& stream );
};

extern logger_t debug_logger;


template<typename data_type>
logger_t& logger_t::operator<<( data_type const& data )
{
	lock_section(ct);

	for(size_t i=0; i<log_streams.size(); ++i)
	{
		log_streams[i].get() << data;
	}

	return *this;
}

namespace log_tag
{
	extern wchar_t const * error;
	extern wchar_t const * warning;
	extern wchar_t const * debug;
	extern wchar_t const * info;
	extern wchar_t const * verbose;
}